/**
观察者模式（Observer Pattern）

意图：定义对象间的一种一对多的依赖关系，当一个对象的状态发生改变时，所有依赖于它的对象都得到通知并被自动更新。
主要解决：一个对象状态改变给其他对象通知的问题，而且要考虑到易用和低耦合，保证高度的协作。
何时使用：一个对象（目标对象）的状态发生改变，所有的依赖对象（观察者对象）都将得到通知，进行广播通知。
如何解决：使用面向对象技术，可以将这种依赖关系弱化。
*/
main(List<String> args) {
  Subject subject = Subject();
  HexaObserver(subject);
  OctalObserver(subject);
  BinaryObserver(subject);

  print("First state change: 15");
  subject.setState(15);

  print("\nSecond state change: 10");
  subject.setState(10);
}

//////////////////////////////////////////////////////////////////

///
/// 创建 Subject 类
///
class Subject {
  List<Observer> _observers = List<Observer>();
  int _state;

  int getState() {
    return _state;
  }

  void setState(int state) {
    this._state = state;
    notifyAllObservers();
  }

  void attach(Observer observer) {
    _observers.add(observer);
  }

  void notifyAllObservers() {
    for (Observer observer in _observers) {
      observer.update();
    }
  }
}

///
/// 创建 Observer 类
///
abstract class Observer {
  Subject _subject;
  void update();
}

///
/// 创建实体观察者类
///
class BinaryObserver extends Observer {
  BinaryObserver(Subject subject) {
    this._subject = subject;
    this._subject.attach(this);
  }

  @override
  void update() {
    print("Binary String: ${_subject.getState().toRadixString(2)}");
  }
}

class OctalObserver extends Observer {
  OctalObserver(Subject subject) {
    this._subject = subject;
    this._subject.attach(this);
  }

  @override
  void update() {
    print("Octal String: ${_subject.getState()}");
  }
}

class HexaObserver extends Observer {
  HexaObserver(Subject subject) {
    this._subject = subject;
    this._subject.attach(this);
  }

  @override
  void update() {
    print("Hex String: ${_subject.getState().toRadixString(16)}");
  }
}
